 /**********************************************************
 *
 * Programme : menu.c
 * ecrit par : Clément HOSOTTE, Jean-Baptiste FUSS
 *
 * resume : fichier source contenant des fonctions utiles
 * au fonctionnement du menu de l'applicarion.
 *
 *
 * date : 15/10/2014
 *
 *
 ***********************************************************
 */


#include "menu.h"
/* 
* Definition pour les structures switch de retour de fonctions
*/
#define CAS_REUSSITE 1
#define CAS_ERREUR_1 -1
#define CAS_ERREUR_2 -2
#define CAS_ERREUR_3 -3
#define CAS_ERREUR_4 -4

/*
 * Fonction : afficheHomeMenu
 *
 * Parametres :
 * int grapheDejaCree : entier afin de diffréncier 2 menus distincts
 *
 * Retour : le menu choisi par l'utilisateur
 
 * Description : Fonction qui permet de choisir une entrée dans le 
 * menu principal
 *
 */
int afficheHomeMenu(int grapheDejaCree){
    /*Affichage des differents menus*/
    printf( "\n###############################################\n");
    printf( "##                   MENU                    ##\n");
    printf( "###############################################\n");
    if (grapheDejaCree == 0) {
        printf( "1 \t: Creer un nouveau graphe\n");
        printf( "2 \t: Charger un graphe existant à partir d'un fichier\n");
    }
    else if (grapheDejaCree == 1) {
    	printf( "1 \t: Afficher le graphe\n");
        printf( "2 \t: Ajouter un sommet au graphe\n");
        printf( "3 \t: Supprimer un sommet du graphe\n");
        printf( "4 \t: Ajouter une arrete au graphe\n");
        printf( "5 \t: Supprimer une arrete\n");
	printf( "6 \t: Postier chinois\n");
        printf( "7 \t: Sauvegarder le graphe\n");
        printf( "8 \t: Supprimer le graphe\n");
    }
    printf( "0 \t: Quitter\n");
    printf( "\n>>Quel est votre choix ? >>\n");
    return saisieEntierClavier();
}

/*
 * Fonction : chargerMenu
 *
 * Parametres :
 * TypGraphe **g : un pointeur de pointeur sur un graphe permettant 
 * de le modifier
 * int grapheDejaCree : entier afin de diffréncier 2 menus distincts
 * int choixMenu : le choix de l'utilisateur
 *
 * Retour : void
 
 * Description : Fonction qui associe une opération au choix de l'utilisateur
 *
 */
void chargerMenu(TypGraphe **g, int grapheDejaCree, int choixMenu){
    /*Appel des fonctions de menus en fonction du choix*/
    if (grapheDejaCree == 0) {
        switch (choixMenu) {
            case 1 : 
            		afficheMenuCreationGraphe(g);
            		break;
            case 2 : 
            		afficheMenuLireGraphe(g);
            		break;
        	case 0 :
        			quitter(g);
        			break;
            default : printf("!!! Ce menu n'existe pas !\n");
        }
    } else if (grapheDejaCree == 1) {
        switch (choixMenu) {        
            case 1 : 
            		afficheMenuAfficherGraphe(*g);
            		break;
            case 2 :
            		afficheMenuAjoutSommet(*g);
            		break;
            case 3 : 
            		afficheMenuSupprimerSommet(*g); 
            		break;
            case 4 : 
            		afficheMenuAjoutArrete(*g); 
            		break;
            case 5 : 
            		afficheMenuSupprimerArrete(*g); 
            		break;
	    case 6 : 
            		afficheMenuPostier(*g); 
            		break;
            case 7 : 
            		afficheMenuSauverGraphe(*g);
            		break;
            case 8 : 
            		quitter(g); 
            		break;
           	case 0 : 
           			quitter(g);
           			break;
            default : 
            		printf("!!! Ce menu n'existe pas !\n");
            		break;
        }
    }
  
}

/*
 * Fonction : afficheMenuCreationGraphe
 *
 * Parametres :
 * TypGraphe **g : un pointeur de pointeur sur un graphe permettant 
 * de le modifier
 *
 * Retour : void
 
 * Description : Fonction qui permet à un utilisateur 
 * de choisir les paramètres de son graphe
 *
 */
void afficheMenuCreationGraphe(TypGraphe **g){
    int nbSommets = 0;	/*Nombre de sommets max pour la creation du graphe*/
    int orientation;
    char estOriente = 0;
     
    system("clear"); //Effacer la console
    printf( "###############################################\n");
    printf( "#          CREATION D'UN NOUVEAU GRAPHE       #\n");
    printf( "###############################################\n");
    /*Demande nombre maximal sommet*/
    while(nbSommets<=0){
        printf( "Entrez le nombre de sommets max pour le graphe :\n");
        nbSommets = saisieEntierClavier();
        if (nbSommets <= 0) {
            printf( "!!!Erreur : le nombre max de sommets doit etre positif et non nul\n");
        }
    }
    //On compare la valeur du caractère reçu (Y,y,N,n)
    while (estOriente != 89 && estOriente != 121 && estOriente != 78 && estOriente != 110) {
        printf("Le graphe doit-il être orienté ? (y/n)\n");
        estOriente = getchar();
        while (getchar() != '\n');
        if(estOriente != 89 && estOriente != 121 && estOriente != 78 && estOriente != 110){
             printf("Erreur lors de la saisie, les deux options sont y(yes) et n(no)\n");
        }
    }
    if (estOriente == 89 || estOriente == 121){
        orientation = 1;
    }
    else {
        orientation = 0;
    }
    /*Appel de la fonction de creation de graphe dans la librairie*/
    *g = creationGraphe(nbSommets,orientation);
    /*Graphe a NULL = probleme*/
    if (g== NULL) {
        printf( "Une erreur est survenue.\n");
    }
    else {
        printf( "Graphe créé avec succès.\n");
    }
}

/*
 * Fonction : afficheMenuAfficherGraphe
 *
 * Parametres :
 * TypGraphe *g : un pointeur sur un graphe 
 *
 * Retour : void
 
 * Description : Fonction qui fait appel à la fonctions
 * d'affichage d'un graphe
 *
 */
void afficheMenuAfficherGraphe(TypGraphe *g){
    system("clear"); //Effacer la console
    
    printf( "###############################################\n");
    printf( "#            AFFICHAGE DU GRAPHE              #\n");
    printf( "###############################################\n");
    
    /*Apel de la fonction d'affichage de la librairie*/
    affichage(g);
    printf( "\n");
}

void afficheMenuAjoutSommet(TypGraphe *g){
    int noSommet, res;
    
    system("clear"); //Effacer la console
    printf( "###############################################\n");
    printf( "#      AJOUT D'UN SOMMET DANS LE GRAPHE       #\n");
    printf( "###############################################\n");
    printf( "Entrez le numero du sommet a ajouter : \n");
    noSommet = saisieEntierClavier();
    res = insertionSommet(g, noSommet);
    /* Affichage des informations relatives à l'opération d'ajout*/
    switch (res) {
    	case CAS_ERREUR_1 :
    			 printf("Le sommet n'est pas compris dans les bornes du graphe.\n"); 
    			 printf("Avortement de la création du sommet.\n");
    			 break;
    	case CAS_ERREUR_2 : 
    			printf("Le sommet existe déjà.\n"); 
    			printf("Avortement de la création du sommet.\n");
    			break;
    	case CAS_REUSSITE : 
    			printf("Ajout du sommet %d dans le graphe.\n", noSommet); 	
				break;
    	default : printf("\n\n");
    			break;
    }
}

/*
 * Fonction : afficheMenuSupprimerSommet
 *
 * Parametres :
 * TypGraphe *g : un pointeur sur un graphe 
 *
 * Retour : void
 
 * Description : Fonction qui permet à un utilisateur
 * de choisir un sommet du graphe à supprimer
 */
void afficheMenuSupprimerSommet(TypGraphe *g){
    int noSommet;	/*Sommet qui va etre supprime*/
    int res; 		/*Le résultat de l'opération de suppression*/
    
    system("clear");
    printf( "###############################################\n");
    printf( "#   SUPPRESSION D'UN SOMMET DANS LE GRAPHE   #\n");
    printf( "###############################################\n");
    printf( "Entrez le numero du sommet a supprimer : \n");
    noSommet = saisieEntierClavier();
    /*Appel de la fonction de la librairie*/
    res = supprimerSommet(g, noSommet);
    /*Indications du résultat de l'opération*/
	switch (res) {
		case CAS_REUSSITE : 
				printf("Suppression du sommet %d \n\n",noSommet);
				break;
		case CAS_ERREUR_1 : 
				printf("Le sommet n'est pas compris dans les bornes du graphe\n");
				printf("Avortement de la suppression du sommet\n");
				break;
		case CAS_ERREUR_2 : 
				printf("Le sommet %d n'est pas initialisé\n",noSommet);
				printf("Avortement de la suppression du sommet\n");
				break;
		default : 	
				printf("\n");
				break;
	}
}

/*
 * Fonction : afficheMenuAjoutArrete
 *
 * Parametres :
 * TypGraphe *g : un pointeur sur un graphe 
 *
 * Retour : void
 
 * Description : Fonction qui permet à un utilisateur
 * de choisir une arête à ajouter entre 2 sommets
 */
void afficheMenuAjoutArrete(TypGraphe *g){
    int sommetOrigine;	/*Sommet d'ou part l'arrete*/
    int sommetDestination;	/*Sommet ou arrive l'arrete*/
    int	ponderation;			/*Ponderation de l'arrete*/
    int res; 						/*Résultat de l'opération d'insertion*/
    
    system("clear");
    printf( "###############################################\n");
    printf( "#      AJOUT D'UNE ARRETE DANS LE GRAPHE      #\n");
    printf( "###############################################\n");
    /*Enregistrement des informations pour la creation de l'arrete*/
    printf( "Entrez le numero du sommet d'origine : \n");
    sommetOrigine = saisieEntierClavier();
    printf( "Entrez le numero du sommet de destination : \n");
    sommetDestination = saisieEntierClavier();
    printf( "Entrez la pondération de l'arrete : \n");
    ponderation = saisieEntierClavier();
    /*Appel des fonctions de la librairie*/
    res = insertionArete(g, sommetOrigine, sommetDestination, ponderation);
    /* Informe l'utilisateur des erreurs survenues*/
    switch (res) {
    	case CAS_ERREUR_1 : 
    			printf("Le sommet d'origine n'est pas compris dans les bornes du graphe.\n"); 
    			printf("Avortement de la création de l'arête\n");
    			break;
    	case CAS_ERREUR_2 : 
    			printf("Le sommet destination n'est pas compris dans les bornes du graphe.\n"); 
    			printf("Avortement de la création de l'arête\n");
    			break;
    	case CAS_ERREUR_3 : 
    			printf("Le sommet d'origine n'est pas initialisé dans le graphe.\n"); 
				printf("Avortement de la création de l'arête\n");				
				break;
    	case CAS_ERREUR_4 : 
    			printf("Le sommet destination n'est pas initialisé dans le graphe.\n"); 
				printf("Avortement de la création de l'arête\n");
    			break;
    	case CAS_REUSSITE : 
    			printf("Réussite de l'opération d'insertion d'une arête\n");
    			break;
    	default : 
    			printf("\n");
    			break;
    }
    
}

/*
 * Fonction : afficheMenuSupprimerArrete
 *
 * Parametres :
 * TypGraphe *g : un pointeur sur un graphe 
 *
 * Retour : void
 
 * Description : Fonction qui permet à un utilisateur
 * de choisir une arête à supprimer entre 2 sommets
 */
void afficheMenuSupprimerArrete(TypGraphe *g){
    int sommetOrigine;	/*Sommet d'ou part l'arrete*/
    int sommetDestination;	/*Sommet ou arrive l'arrete*/
    
    system("clear");
    printf( "###############################################\n");
    printf( "#  SUPPRESSION D'UNE ARRETE DANS LE GRAPHE    #\n");
    printf( "###############################################\n");
    /*Enregistrement des informations pour supprimer l'arrete*/
    printf( "Entrez le numero du sommet d'origine : \n");
    sommetOrigine = saisieEntierClavier();
    printf( "Entrez le numero du sommet de destination : \n");
    sommetDestination = saisieEntierClavier(); 
    /*Appel des fonctions correspondantes de la librairie*/
    if (supprimerArete(g, sommetOrigine, sommetDestination) != 1) {
        printf( "L'arête (%d,%d) n'existe pas.\n",sommetOrigine,sommetDestination);
    }
    else {
        printf("Suppression de l'arête (%d,%d)\n",sommetOrigine,sommetDestination);
    }   
}

/*
 * Fonction : afficheMenuSauverGraphe
 *
 * Parametres :
 * TypGraphe *g : un pointeur sur un graphe 
 *
 * Retour : void
 
 * Description : Fonction qui permet à un utilisateur
 * de sauvegarder un graphe dans un fichier texte de son choix
 */
void afficheMenuSauverGraphe(TypGraphe *g) {
	char* fich ;  /* Le nom du fichier à sauvegarder */
	int res; /* Le résultat de l'opération de sauvegarde*/
	
	system("clear");
	printf( "###############################################\n");
    printf( "#              SAUVEGARDE DU GRAPHE           #\n");
    printf( "###############################################\n");
	fich = malloc(256*sizeof(char)) ;
	printf("\nQuel est le nom du fichier à créer pour la sauvegarde du graphe?\n") ;
	scanf("%s",fich) ;
	res = sauverGraphe(g,fich);
	if (res == 1) {
		printf("Réussite de la sauvegarde du graphe dans le fichier %s\n", fich);
	}
	else {
		printf("Echec lors de l'ouverture du fichier\n");
		printf("Avortement de l'opération de sauvegarde\n");
	}
	free(fich) ;
}

/*
 * Fonction : afficheMenuLireGraphe
 *
 * Parametres :
 * TypGraphe **g : un pointeur de pointeur sur un graphe 
 *
 * Retour : void
 
 * Description : Fonction qui permet à un utilisateur
 * de lire un graphe depuis un fichier texte de son choix
 */
void afficheMenuLireGraphe(TypGraphe **g){
	char* fich ;  /* Le nom du fichier à sauvegarder */
	
	system("clear");
	printf( "###############################################\n");
    printf( "#               LECTURE DU GRAPHE             #\n");
    printf( "###############################################\n");
	fich = malloc(256*sizeof(char)) ;
	printf("\nQuel est le nom du fichier contenant le graphe à créer (chemin relatif)?\n") ;
	scanf("%s",fich) ;
	*g = lecture(fich);
	if (*g != NULL) {
		printf("Réussite de la lecture du graphe depuis le fichier %s\n", fich);
	}
	else {
		printf("Echec lors de l'ouverture du fichier\n");
		printf("Avortement de l'opération de lecture\n");
	}
	free(fich) ;
}

/*
 * Fonction : viderBuffer
 *
 * Parametres : 
 *
 * Retour : void
 
 * Description : Fonction qui permet de vider un buffer
 */
void viderBuffer(){
    char c;
    /*On recupere tous les caracteres du buffer jusqu'a la fin ce qui a pour
     effet de le vider*/
    while ((c = getchar()) != '\n' && c != EOF) ;
}

/*
 * Fonction : saisieEntierClavier
 *
 * Parametres : 
 *
 * Retour : l'entier saisi par l'utilisateur
 
 * Description : Fonction qui à l'utilisateur de 
 * taper un entier au clavier et qui contrôle la saisie
 */
int saisieEntierClavier(){
	int choixMenu; /*Entier representant le choix dans le menu*/
	/* Vérification de la saisie*/
    while (scanf("%i", &choixMenu) != 1) {
    	/* Vidange du flux*/
    	scanf("%*[^\n]");
		getchar();
		printf("Erreur lors de la saisie, veuillez recommencer\n");
    }
    scanf("%*[^\n]");
	getchar();
    return choixMenu;
}


void afficheMenuPostier(TypGraphe* g){
  //printf(" appel : \n ");
  calculCycleEulerien(g,0);
  
  
}
